/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elaborate.tool.messenger.yahoo;

import com.fasterxml.jackson.databind.ObjectMapper;
import elaborate.tool.messenger.Contact;
import elaborate.tool.messenger.ContactListener;
import elaborate.tool.messenger.ContactStatus;
import elaborate.tool.messenger.SimpleContactImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * get contact list along with status
 * also monitor contact status change
 * @author lendle
 */
public class YahooContactsLoader extends Thread{
    private String oauth_consumer_key;
    private String oauth_token;
    private String consumer_secret;
    private String oauthSecret;
    private String sessionId;
    private HttpUtil httpUtil=null;
    private List<Contact> contacts=new ArrayList<Contact>();
    private List<ContactListener> listeners=new ArrayList<ContactListener>();
    
    public YahooContactsLoader(String oauth_consumer_key, String consumer_secret, String oauth_token, String oauthSecret, 
            String sessionId) {
        this.oauth_consumer_key = oauth_consumer_key;
        this.oauth_token = oauth_token;
        this.consumer_secret = consumer_secret;
        this.oauthSecret = oauthSecret;
        this.sessionId = sessionId;
        
        this.setDaemon(true);
        
        //initialize httputil
        this.httpUtil=new HttpUtil(oauth_consumer_key, consumer_secret, oauth_token, oauthSecret, sessionId, null);
        try {
            reloadContacts();
        } catch (Exception ex) {
            Logger.getLogger(YahooContactsLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        this.start();
    }
    
    public void run() {
        try {
            //double oauth_nonce=24829.2330;
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Logger.getLogger(YahooContactsLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
        while (true) {
            try {
                String ret=httpUtil.doGet("http://developer.messenger.yahooapis.com/v1/notifications" + "?sid=" + sessionId+"&seq=0");
                //System.out.println(ret);
                ObjectMapper mapper = new ObjectMapper();
                Map map = mapper.readValue(ret, Map.class);
                List responses=(List) map.get("responses");
                for(int i=0; responses!=null && i<responses.size(); i++){
                    Map message=(Map) responses.get(i);
                    if(message.containsKey("buddyInfo")){
                        Map buddyInfoMap=(Map) message.get("buddyInfo");
                        List contactsList=(List) buddyInfoMap.get("contact");
                        Map onlineContacts=new HashMap();
                        for(int j=0; contactsList!=null && j<contactsList.size(); j++){
                            Map contactMap=(Map) contactsList.get(j);
                            String sender=(String) contactMap.get("sender");
                            onlineContacts.put(sender, "");
                            Integer state=Integer.valueOf(""+contactMap.get("presenceState"));
                            for(Contact contact : this.getContacts()){
                                if(contact.getId().equals(sender)){
                                    //System.out.println(contact.getId()+":"+contact.getStatus()+":"+state);
                                    if(state==0 && contact.getStatus().equals(ContactStatus.ONLINE)==false){
                                        ((SimpleContactImpl)contact).setStatus(ContactStatus.ONLINE);
                                        fireStatusChange(contact);
                                    }
                                    else if(state==10 && contact.getStatus().equals(ContactStatus.AWAY)==false){
                                        ((SimpleContactImpl)contact).setStatus(ContactStatus.AWAY);
                                        fireStatusChange(contact);
                                    }
                                }
                            }
                        }
                        for(Contact contact : this.getContacts()){
                            if(onlineContacts.containsKey(contact.getId())==false && contact.getStatus().equals(ContactStatus.OFFLINE)==false){
                                ((SimpleContactImpl)contact).setStatus(ContactStatus.OFFLINE);
                                fireStatusChange(contact);
                            }
                        }
                    }
                }
                
                //System.out.println("process message: " + message);
            } catch (Exception e) {
                e.printStackTrace();
                Logger.getLogger(this.getClass().getName()).severe(e.getMessage());
            }
            try {
                Thread.sleep(60000);
            } catch (InterruptedException ex) {
                Logger.getLogger(YahooContactsLoader.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    private void fireStatusChange(Contact contact){
        for(ContactListener l : this.listeners){
            l.onContactStatusChanged(contact);
        }
    }
    
    private void reloadContacts() throws Exception{
        List<Contact> contacts=new ArrayList<Contact>();
        String ret=httpUtil.doGet("http://developer.messenger.yahooapis.com/v1/contacts?sid=" + this.sessionId);
        ObjectMapper mapper = new ObjectMapper();
        Map map = mapper.readValue(ret, Map.class);
        List list=(List) map.get("contacts");
        for(int i=0; list!=null && i<list.size(); i++){
            Map _map=(Map) list.get(i);
            Map contactMap=(Map) _map.get("contact");
            if(contactMap!=null){
                this.contacts.add(new SimpleContactImpl((String) contactMap.get("id"), ContactStatus.OFFLINE));
            }
        }
    }
    
    public List<Contact> getContacts(){
        return this.contacts;
    }
    
    public void addContactListener(ContactListener l){
        if(this.listeners.contains(l)==false){
            this.listeners.add(l);
        }
    }
    
    public void removeContactListener(ContactListener l){
        if(this.listeners.contains(l)){
            this.listeners.remove(l);
        }
    }
}
